﻿using System;
using System.ComponentModel;
using System.IO;
using System.Linq.Expressions;
using System.Windows.Input;
using JetBrains.Annotations;

using esquireclockscreensaver.Utils;

namespace esquireclockscreensaver
{
    internal sealed class MainWindowViewModel : INotifyPropertyChanged
    {
        private bool _isFirstMove = true;

        private const string EsquireClockDirectory = "EsquireClock";

        private bool _isReadyToShowVideo;

        public bool IsReadyToShowVideo
        {
            get { return _isReadyToShowVideo; }
            set
            {
                _isReadyToShowVideo = value;
                OnPropertyChanged(() => IsReadyToShowVideo);
            }
        }

        private bool _needCloseWindow;

        public bool NeedCloseWindow
        {
            get { return _needCloseWindow; }
            set
            {
                _needCloseWindow = value;
                OnPropertyChanged(() => NeedCloseWindow);
            }
        }

        [UsedImplicitly]
        public ICommand MouseMove
        {
            get { return new GenericCommand(OnMouseMove); }
        }

        [UsedImplicitly]
        public ICommand VideoEnded
        {
            get { return new GenericCommand(UpdateVideoPath); }
        }

        private string _exceptionText;

        public string ExceptionText
        {
            get { return _exceptionText; }
            set
            {
                _exceptionText = value;
                OnPropertyChanged(() => ExceptionText);
            }
        }

        private string _videoPath;

        public string VideoPath
        {
            get { return _videoPath; }
            set
            {
                _videoPath = value;
                OnPropertyChanged(() => VideoPath);
            }
        }

        private TimeSpan _timeOffset;

        public TimeSpan TimeOffset
        {
            get { return _timeOffset; }
            set 
            {
                _timeOffset = value;OnPropertyChanged(() => TimeOffset);
            }
        }

        private bool _showWindowNormal;
        public bool ShowWindowNormal
        {
            get { return _showWindowNormal; }
            set { _showWindowNormal = value; OnPropertyChanged(()=>ShowWindowNormal); }
        }

        public MainWindowViewModel()
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;

            if(!Directory.Exists(EsquireClockDirectory))
            {
                ExceptionText = string.Format("Please download esquire torrent to the {0} directory.", EsquireClockDirectory);
                ShowWindowNormal = true;
                return;
            }
            ShowWindowNormal = false;
            UpdateVideoPath();
        }

        private void UpdateVideoPath()
        {
            IsReadyToShowVideo = true;

            var time = DateTime.Now;
            var minutes = (time.Minute/10)*10;
            var seconds = (time.Minute - minutes) * 60 + time.Second;

            VideoPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, EsquireClockDirectory, string.Format("big_{0:00}-{1:00}.mp4", time.Hour, minutes));

            TimeOffset = new TimeSpan(0,0,seconds);

        }

        private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
        {
            ExceptionText = unhandledExceptionEventArgs.ExceptionObject.ToString();
        }

        private void OnMouseMove()
        {
            if (!_isFirstMove)
            {
                NeedCloseWindow = true;
            }
            else
            {
                _isFirstMove = false;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged<T>(Expression<Func<T>> propertyGetter)
        {
            OnPropertyChanged(ReflectionUtils.GetPropertyName(propertyGetter));
        }

        private void OnPropertyChanged(string name)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}